#region imported Namespaces
using System;
using System.Data;

using DistribPeriodConstants = PHSRAG.Insight21.Personnel.Constants.DistributionPeriodConstants;
using SplitsConstants = PHSRAG.Insight21.Personnel.Constants.DistributionSplitsConstants;
#endregion

namespace PHSRAG.Insight21.Personnel
{
	#region DistributionPeriod class
	/// <summary>
	/// The DistributionPeriod class is the facade over the details for a single distribution period.
	/// It will also hold the distribution splits which fall with in the distribution period.
	/// </summary>
	public class DistributionPeriod
	{		
		#region Constants
		private const decimal MinimumDollarAmount = -1;
		private const decimal MaximumDollarAmount = 1;
		#endregion

		#region Instance Variables
		private DistributionSplits splits;
		private DataRow periodRow;
		#endregion

		#region Public Properties
		/// <summary>
		/// Get the effective date for the present distribution period
		/// </summary>
		public string EffectiveDate
		{
			get
			{
				return ((DateTime)periodRow[DistribPeriodConstants.EffectiveDateColumnName]).
					ToString("MM/dd/yyyy");
			}
		}
		/// <summary>
		/// Get the expiration date for the present distribution period
		/// </summary>
		public string ExpirationDate
		{
			get
			{
				return ((DateTime)periodRow[DistribPeriodConstants.ExpirationDateColumnName]).
					ToString("MM/dd/yyyy");
			}
		}
		/// <summary>
		/// Get the total annual rate for the present distribution period
		/// </summary>
		public decimal TotalAnnualRate
		{
			get
			{
				object totalAnnualRate = periodRow[DistribPeriodConstants.TotalAnnualRateColumnName];
				return (totalAnnualRate == DBNull.Value)?0:(decimal)totalAnnualRate;
			}
		}
		/// <summary>
		/// Get the total percent effort for the present distribution period
		/// </summary>
		public decimal TotalPercentEffort
		{
			get
			{
				object totalPercentEffort = periodRow[DistribPeriodConstants.TotalPercentEffortColumnName];
				return (totalPercentEffort == DBNull.Value)?0:(decimal)totalPercentEffort;
			}
		}
		/// <summary>
		/// Get the total amount to be paid for the present distribution period
		/// </summary>
		public decimal TotalToBePaid
		{
			get
			{
				object totalToBePaid = periodRow[DistribPeriodConstants.TotalToBePaidColumnName];
				return (totalToBePaid == DBNull.Value)?0:(decimal)totalToBePaid;
			}
		}
		/// <summary>
		/// Get the salary for the present distribution period
		/// </summary>
		public decimal CurrentSalary 
		{
			get
			{
				return (decimal)periodRow[DistribPeriodConstants.CurrentSalaryColumnName];
			}
		}
		/// <summary>
		/// Get the allocation warning for the present distribution period
		/// Generated by comparing the CurrentSalary for the period with the TotalAnnualRate for the period
		/// Return empty string if the there is no mismatch
		/// </summary>
		public string AllocationWarning
		{
			get
			{
				decimal difference = CurrentSalary - TotalAnnualRate;				
				if(difference > MaximumDollarAmount)
					return string.Format("Salary Under Allocated {0} for period {1}-{2}",
						(CurrentSalary - TotalAnnualRate).ToString("c"),EffectiveDate,ExpirationDate);
				else if(difference < MinimumDollarAmount)
					return string.Format("Salary Over Allocated {0} for period {1}-{2}",
						(CurrentSalary - TotalAnnualRate).ToString("c"),EffectiveDate,ExpirationDate);
				else
					return string.Empty;
			}
		}
		/// <summary>
		/// Get the effort warning for the present distribution period
		/// Generated by checking the TotalPercentEffort for the current distribution period
		/// Return empty string if the there is no mismatch
		/// </summary>
		public string EffortWarning
		{
			get
			{
				if(TotalPercentEffort > 100)
					return string.Format("Effort Over Assigned for period {0}-{1}",EffectiveDate,ExpirationDate);
				else if(TotalPercentEffort < 100)
					return string.Format("Effort Under Assigned for period {0}-{1}",EffectiveDate,ExpirationDate);
				else
					return string.Empty;
			}
		}
		#endregion

		#region Public Contained Objects
		/// <summary>
		/// Get the DistributionSplits for the current DistributionPeriod
		/// </summary>
		public DistributionSplits Splits
		{
			get
			{
				if(splits == null)
				{
					splits = new DistributionSplits();
					splits.Load(GetSplitsDataforPeriod());
				}
				return splits;
			}
		}
		#endregion

		#region Constructor
		/// <summary>
		/// Set the dataRow to the instance variable
		/// </summary>
		/// <param name="dataRow">DataRow containing distribution period data</param>
		public DistributionPeriod(DataRow dataRow)
		{
			periodRow = dataRow;
		}
		#endregion

		#region Private methods
		/// <summary>
		/// Get the table with the split information for the present distribution period
		/// </summary>
		/// <returns>A datatable with the splits for the current distribution period</returns>
		private DataTable GetSplitsDataforPeriod()
		{
			DataTable splitsTable = 
				periodRow.Table.DataSet.Tables[SplitsConstants.DistributionSplitsTableName];
			
			DataRow[] splitRows = splitsTable.Select
				(string.Format("{0} = '{1}' AND {2} = '{3}'",
				DistribPeriodConstants.EffectiveDateColumnName,EffectiveDate,
				DistribPeriodConstants.ExpirationDateColumnName,ExpirationDate));

			DataTable splitsTableforPeriod = splitsTable.Clone();

			foreach(DataRow splitRow in splitRows)
                splitsTableforPeriod.ImportRow(splitRow);

			return splitsTableforPeriod;
		}
		#endregion
	}
	#endregion
}